package com.personal.dao.template;

import org.springframework.jdbc.core.JdbcTemplate;

import com.personal.dao.cache.Cache;
import com.personal.dao.cache.CacheKey;
import com.personal.dao.dialect.DaoDialect;
import com.personal.dao.handler.BatchSqlHandler;
import com.personal.dao.handler.SqlHandler;
import com.personal.dao.sign.Signable;
import com.personal.dao.sql.BatchSql;
import com.personal.dao.sql.Sql;

/**
 * CachingDaoTemplateBean
 * 
 * @author qq
 *
 */
public class CachingDaoTemplateBean implements DaoTemplate
{

	// private TransactionalCache transactionalCache;
	// 暂时没必须要使用事物缓存，并且其实非线程安全的，如果使用也需要将其改为线程安全的

	private Cache cache;

	private DaoTemplate delegate;

	public CachingDaoTemplateBean(DaoTemplate delegate, Cache cache)
	{
		super();
		this.cache = cache;
		// this.transactionalCache = new TransactionalCache(cache);
		this.delegate = delegate;
	}

	@Override
	public <V> V execute(Sql sql, SqlHandler<V> handler)
	{
		// 刷新缓存
//		flushCacheIfRequired(handler);
//		boolean commit = false;
//		try
//		{
		// 判断是否需要读取缓存
		if (sql.isReadCache())
		{
			// 创建CacheKey
			CacheKey key = delegate.createCacheKey(sql, handler);
			@SuppressWarnings("unchecked")
			V v =  (V) this.cache.getObject(key);
			if (v == null)
			{
				v = delegate.execute(sql, handler);
				// 检测是否需要清除缓存
				if (handler.isFlushCache())
				{
					cache.clear();
				}
				if (v != null)
				{
					this.cache.putObject(key, v);
//						commitCache();
//					commit = true;
				}
				return v;
			}
			return v;
		}
		V v = delegate.execute(sql, handler);
		// 检测是否需要清除缓存
		if (handler.isFlushCache())
		{
			cache.clear();
		}
		return v;
//		} finally
//		{
//			if (handler.isFlushCacheRequired() && !commit)
//			{
//				commitCache();	
//			}
//		}
	}
	
	@Override
	public <V> V execute(BatchSql sql, BatchSqlHandler<V> handler)
	{
		// 刷新缓存
//		flushCacheIfRequired(handler);
//		boolean commit = false;
//		try
//		{
		// 判断是否需要读取缓存
		if (sql.isReadCache())
		{
			// 创建CacheKey
			CacheKey key = delegate.createCacheKey(sql, handler);
			@SuppressWarnings("unchecked")
			V v =  (V) this.cache.getObject(key);
			if (v == null)
			{
				v = delegate.execute(sql, handler);
				// 检测是否需要清除缓存
				if (handler.isFlushCache())
				{
					cache.clear();
				}
				if (v != null)
				{
					this.cache.putObject(key, v);
//						commitCache();
//					commit = true;
				}
				return v;
			}
			return v;
		}
		V v = delegate.execute(sql, handler);
		// 检测是否需要清除缓存
		if (handler.isFlushCache())
		{
			cache.clear();
		}
		return v;
//		} finally
//		{
//			if (handler.isFlushCacheRequired() && !commit)
//			{
//				commitCache();	
//			}
//		}
	}

	@Override
	public <V> CacheKey createCacheKey(Signable... signables)
	{
		return delegate.createCacheKey(signables);
	}

	@Override
	public DaoDialect getDaoDialect()
	{
		return delegate.getDaoDialect();
	}

	@Override
	public JdbcTemplate geJdbcTemplate()
	{
		return delegate.geJdbcTemplate();
	}

//	private <T> void flushCacheIfRequired(SqlHandler<T> handler)
//	{
//		if (handler.isFlushCacheRequired())
//		{
//			this.transactionalCache.clear();
//		}
//	}
//	
//	private void commitCache()
//	{
//		this.transactionalCache.commit();
//	}
//	
//	private void rollBackCache()
//	{
//		this.transactionalCache.rollback();
//	}

}
